---
title: "Publishing an MCP Server | MCP"
description: Guide to setting up and building a Mastra MCP server using the stdio transport, and publishing it to NPM.
---

import Steps from "@site/src/components/Steps";
import StepItem from "@site/src/components/StepItem";

# Publishing an MCP Server

This example guides you through setting up a basic Mastra MCPServer using the stdio transport, building it, and preparing it for publishing to NPM.

## Install dependencies

Install the necessary packages:

```bash
pnpm add @mastra/mcp @mastra/core tsup
```

## Setting up an MCP Server

<Steps>

<StepItem>

Create a file for your stdio server, for example, `/src/mastra/stdio.ts`.

</StepItem>

<StepItem>

Add the following code to the file. Remember to import your actual Mastra tools and name the server appropriately.

```typescript title="src/mastra/stdio.ts" copy
#!/usr/bin/env node
import { MCPServer } from "@mastra/mcp";
import { weatherTool } from "./tools";

const server = new MCPServer({
  name: "my-mcp-server",
  version: "1.0.0",
  tools: { weatherTool },
});

server.startStdio().catch((error) => {
  console.error("Error running MCP server:", error);
  process.exit(1);
});
```

</StepItem>

<StepItem>

Update your `package.json` to include the `bin` entry pointing to your built server file and a script to build the server with both ESM and CJS outputs.

```json title="package.json" copy
{
  "bin": "dist/stdio.mjs",
  "scripts": {
    "build:mcp": "tsup src/mastra/stdio.ts --format esm,cjs --no-splitting --dts && echo '#!/usr/bin/env node' | cat - dist/stdio.mjs > temp && mv temp dist/stdio.mjs && chmod +x dist/stdio.mjs"
  }
}
```

The build command generates both ESM (`.mjs`) and CJS (`.cjs`) outputs for maximum compatibility. The shebang (`#!/usr/bin/env node`) is prepended to the ESM artifact to make it directly executable, and the `bin` entry points to this file.

</StepItem>

<StepItem>

Run the build command:

```bash
pnpm run build:mcp
```

This will compile your server code into both ESM and CJS formats and make the ESM output file executable. On Unix-like systems, the `chmod +x` step makes the file directly executable. Windows users may need to use WSL or handle execution through Node.js directly.

</StepItem>

</Steps>

## Publishing to NPM

To make your MCP server available for others (or yourself) to use via `npx` or as a dependency, you can publish it to NPM.

<Steps>

<StepItem>

Ensure you have an NPM account and are logged in (`npm login`).

</StepItem>

<StepItem>

Make sure your package name in `package.json` is unique and available.

</StepItem>

<StepItem>

Run the publish command from your project root after building:

```bash
npm publish --access public
```

For more details on publishing packages, refer to the [NPM documentation](https://docs.npmjs.com/creating-and-publishing-scoped-public-packages).

</StepItem>

</Steps>

## Using a published MCP Server

Once published, your MCP server can be used by an `MCPClient` by specifying the command to run your package. You can also use any other MCP client like Claude desktop, Cursor, or Windsurf.

```typescript
import { MCPClient } from "@mastra/mcp";

const mcp = new MCPClient({
  servers: {
    // Give this MCP server instance a name
    yourServerName: {
      command: "npx",
      args: ["-y", "@your-org-name/your-package-name@latest"], // Replace with your package name
    },
  },
});

// You can then get tools or toolsets from this configuration to use in your agent
const tools = await mcp.getTools();
const toolsets = await mcp.getToolsets();
```

Note: If you published without an organization scope, the `args` might just be `["-y", "your-package-name@latest"]`.
